import axios from 'axios'
import router from '@/router/index'
import store from '@/store'
import { Notify, Loading } from "element-ui";
import { TokenKey, getToken } from '@/utils/auth'

// 接口成功code值
const REQUEST_SUCCESS_CODE = 0;
const REQUEST_NO_AUTH_CODE = 401;
const REQUEST_INVALID_TOKEN_CODE = 402;
const REQUEST_NO_TOKEN_CODE = 403;
// 请求默认配置
const REQUEST_DETAILS_CONFIG = {
  // 请求地址
  url: "",
  // 请求类型
  method: "POST",
  // 是否表单提交
  isForm: false,
  // 是否需要权限
  isAuth: true,
  // 成功情况下，是否提示message信息
  isTip: false,
  // 是否需要loading
  isLoading: true
};
// 处理多次拦截到登录过期标识 应只返回一次
let toKenStatus = true;

// 创建axios实例
const service = axios.create({
  // 接口公共
  baseURL: process.env.VUE_APP_API_ROOT,
  // 请求超时时间
  timeout: 15000,
});

// request拦截器  请求前  添加请求头在此添加
service.interceptors.request.use(config => {
  // config.headers['Scope-Of-Use'] = 'platform/1.0 (Windows NT 10.0; Win64; x64)';
  // 判断权限
  if (config.isAuth) {
    // 让每个请求携带自定义token 请根据实际情况自行修改
    config.headers[TokenKey] = getToken();
  }
  // 判断是否需要loading
  if (config.isLoading) {

    config.loadingShow = Loading.service({
      lock: true,
      text: '加载中...',
      spinner: 'el-icon-loading',
      background: 'rgba(0, 0, 0, 0.7)'
    });
  }
  // 判断是否需要表单提交
  if (config.isForm) {
    config.headers["Content-Type"] = "application/x-www-form-urlencoded";
    if (config.data) {
      config.transformRequest = data => {
        let ret = '';
        for (let it in data) {
          ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&';
        }
        ret = ret.substr(0, ret.length - 1);
        return ret;
      }
    }
  }
  return config
}, error => {
  Promise.reject(error)
})

// response拦截器 拦截返回的数据 统一处理
service.interceptors.response.use(
  response => {
    let config = response.config;
    let res = response.data;
    // 关闭loading
    if (config.loadingShow) { config.loadingShow.close(); }
    // 成功
    if (res.status === REQUEST_SUCCESS_CODE) {
      // 消息提示
      if (config.isTip) {
        Notify.success({
          // title: '消息',
          message: res.message
        });
      }
      return response.data
    } else { // 错误
      if (res.status === REQUEST_NO_AUTH_CODE || res.status === REQUEST_NO_TOKEN_CODE || res.status === REQUEST_INVALID_TOKEN_CODE) {
        if (toKenStatus) {
          toKenStatus = false;
          router.replace({
            path: '/login'
          })
        }
      } else {
        Notify.error({
          // title: '消息',
          message: res.message
        });
      }
      return Promise.reject(res.message);
    }
  },
  (error) => {
    let config = error.config;
    if (config && config.loadingShow) { config.loadingShow.close(); }
    Notify.error({
      // title: '消息',
      message: res.message
    });
    return Promise.reject(error)
  }
);

/**
 *
 * @param requestCustomConfig   请求自定义配置
 * @param params  接口参数
 * @returns {Promise<unknown>}  回调
 */
function request(requestCustomConfig, params = {}) {
  // 合并配置
  let config = Object.assign({}, REQUEST_DETAILS_CONFIG, requestCustomConfig);
  // 接口方法大写
  config.method = config.method.toUpperCase();
  // 发起请求
  return new Promise((resolve, reject) => {
    switch (config.method) {
      case "POST": service.post(config.url, params, { ...config }).then(resp => resolve(resp.data)).catch(err => reject(err)); break;
      case "PUT": service.put(config.url, params, { ...config }).then(resp => resolve(resp.data)).catch(err => reject(err)); break;
      case "DELETE": service.delete(config.url, { params, ...config }).then(resp => resolve(resp.data)).catch(err => reject(err)); break;
      case "GET":
      default: service.get(config.url, { params: params, ...config }).then(resp => resolve(resp.data)).catch(err => reject(err)); break;
    }
  });
}
// 注册到vue实例
export default {
  install: function (Vue) {
    Vue.prototype.$request = request
  }
}
